﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Web;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
using System.Globalization;

namespace IRongs.Wbt.Processor2
{
    public class SinaOAuth : OAuthBase, IWbtRequester
    {
        public SinaOAuth()
        {
            ProfilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Profile");
        }

        private readonly string ProfilePath;
        public const string WbtKey = "Sina";
        public SinaOAuth(string screenName)
            : this()
        {
            profileFile = Path.Combine(ProfilePath, string.Format("{0}_{1}", WbtKey, screenName));
            LoadProfile(screenName);
        }

        private string profileFile;
        private void LoadProfile(string screenName)
        {

        }

        public void SaveProfile(string key)
        {

        }

        public const string REQUEST_TOKEN = "http://api.t.sina.com.cn/oauth/request_token";
        public const string AUTHORIZE = "http://api.t.sina.com.cn/oauth/authorize";
        public const string ACCESS_TOKEN = "http://api.t.sina.com.cn/oauth/access_token";

        public string Token { get; private set; }

        public string TokenSecret { get; private set; }

        public string Verifier { get; private set; }

        public string UserId { get; private set; }

        public string ScreenName { get; private set; }

        private string _consumerKey = "1341795061";
        private string _consumerSecret = "4d74ceadd38764d6c0123222885e8a26";

        public string GetRequestToken()
        {
            string ret = null;
            string response = OAuthWebRequest(REQUEST_TOKEN, string.Empty, Method.GET);
            if (response.Length > 0)
            {
                NameValueCollection qs = HttpUtility.ParseQueryString(response);
                if (qs["oauth_token"] != null)
                {
                    this.Token = qs["oauth_token"];
                    this.TokenSecret = qs["oauth_token_secret"];
                    ret = AUTHORIZE + "?oauth_token=" + this.Token;
                }
            }

            return ret;
        }

        public void GetAccessToken(string authVerifier)
        {
            this.Verifier = authVerifier;

            string response = OAuthWebRequest(ACCESS_TOKEN, string.Empty, Method.GET);

            if (response.Length > 0)
            {
                NameValueCollection qs = HttpUtility.ParseQueryString(response);
                if (qs["oauth_token"] != null)
                {
                    this.Token = qs["oauth_token"];
                }
                if (qs["oauth_token_secret"] != null)
                {
                    this.TokenSecret = qs["oauth_token_secret"];
                }
                if (qs["user_id"] != null)
                {
                    this.UserId = qs["user_id"];
                }
            }
        }

        public string OAuthWebRequest(string url, string data, Method method)
        {
            string outUrl = "";
            string querystring = "";
            string ret = "";
            data += "&source=" + _consumerKey;
            if (method == Method.POST)
            {
                if (data.Length > 0)
                {
                    NameValueCollection qs = HttpUtility.ParseQueryString(data);
                    data = "";
                    foreach (string key in qs.AllKeys)
                    {
                        if (data.Length > 0)
                        {
                            data += "&";
                        }
                        qs[key] = HttpUtility.UrlEncode(qs[key]);
                        qs[key] = this.UrlEncode(qs[key]);
                        data += (key + "=" + qs[key]);

                    }
                    if (url.IndexOf("?") > 0)
                    {
                        url += "&";
                    }
                    else
                    {
                        url += "?";
                    }
                    url += data;
                }
            }

            Uri uri = new Uri(url);

            string nonce = this.GenerateNonce();
            string timeStamp = this.GenerateTimeStamp();

            //Generate Signature
            string sig = this.GenerateSignature(uri,
                this._consumerKey,
                this._consumerSecret,
                this.Token,
                this.TokenSecret,
                this.Verifier,
                method.ToString(),
                timeStamp,
                nonce,
                out outUrl,
                out querystring);


            querystring += "&oauth_signature=" + HttpUtility.UrlEncode(sig);

            if (method == Method.POST)
            {
                data = querystring;
                querystring = "";
            }

            if (querystring.Length > 0)
            {
                outUrl += "?";
            }

            if (method == Method.POST || method == Method.GET)
                ret = WebRequestHelper.WebRequest(outUrl + querystring, data, method);

            return ret;
        }

        public string OAuthWebRequestWithPic(string url, string postData, string filepath, string picName, Method method)
        {
            var UploadApiUrl = url;
            string status = postData.Split('=').GetValue(1).ToString();
            postData += "&source=" + _consumerKey;

            if (postData.Length > 0)
            {
                NameValueCollection qs = HttpUtility.ParseQueryString(postData);
                postData = "";
                foreach (string key in qs.AllKeys)
                {
                    if (postData.Length > 0)
                    {
                        postData += "&";
                    }
                    qs[key] = HttpUtility.UrlEncode(qs[key]);
                    qs[key] = this.UrlEncode(qs[key]);
                    postData += (key + "=" + qs[key]);

                }
                if (url.IndexOf("?") > 0)
                {
                    url += "&";
                }
                else
                {
                    url += "?";
                }
                url += postData;
            }

            var oauthSignaturePattern = "OAuth oauth_consumer_key=\"{0}\", oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"{1}\", oauth_nonce=\"{2}\", oauth_version=\"1.0\", oauth_token=\"{3}\",oauth_signature=\"{4}\"";

            var contentEncoding = "iso-8859-1";

            string normalizedString, normalizedParameters;
            var timestamp = this.GenerateTimeStamp();
            var nounce = this.GenerateNonce();

            var signature = this.GenerateSignature(
                                new Uri(url),
                                this._consumerKey,
                                this._consumerSecret,
                                this.Token,
                                this.TokenSecret,
                                this.Verifier,
                                method.ToString(),
                                timestamp,
                                nounce,
                                out normalizedString,
                                out normalizedParameters);
            signature = HttpUtility.UrlEncode(signature);

            var boundary = Guid.NewGuid().ToString();
            var request = (HttpWebRequest)System.Net.WebRequest.Create(UploadApiUrl);

            request.PreAuthenticate = true;
            request.AllowWriteStreamBuffering = true;
            request.Method = method.ToString();
            request.UserAgent = "Jakarta Commons-HttpClient/3.1";
            var authorizationHeader = string.Format(
                                        CultureInfo.InvariantCulture,
                                        oauthSignaturePattern,
                                        this._consumerKey,
                                        timestamp,
                                        nounce,
                                        this.Token,
                                        signature);
            request.Headers.Add("Authorization", authorizationHeader);

            var header = string.Format("--{0}", boundary);
            var footer = string.Format("--{0}--", boundary);

            var contents = new StringBuilder();
            request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
            contents.AppendLine(header);
            contents.AppendLine(String.Format("Content-Disposition: form-data; name=\"{0}\"", "status"));
            contents.AppendLine("Content-Type: text/plain; charset=US-ASCII");
            contents.AppendLine("Content-Transfer-Encoding: 8bit");
            contents.AppendLine();
            contents.AppendLine(status);

            contents.AppendLine(header);
            contents.AppendLine(string.Format("Content-Disposition: form-data; name=\"{0}\"", "source"));
            contents.AppendLine("Content-Type: text/plain; charset=US-ASCII");
            contents.AppendLine("Content-Transfer-Encoding: 8bit");
            contents.AppendLine();
            contents.AppendLine(this._consumerKey);


            contents.AppendLine(header);
            string fileHeader = string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"", "pic", picName);
            string fileData = System.Text.Encoding.GetEncoding(contentEncoding).GetString(File.ReadAllBytes(@filepath));

            contents.AppendLine(fileHeader);
            contents.AppendLine("Content-Type: application/octet-stream; charset=UTF-8");
            contents.AppendLine("Content-Transfer-Encoding: binary");
            contents.AppendLine();
            contents.AppendLine(fileData);
            contents.AppendLine(footer);

            byte[] bytes = Encoding.GetEncoding(contentEncoding).GetBytes(contents.ToString());
            request.ContentLength = bytes.Length;

            return WebRequestHelper.WebRequest(request, string.Empty, method);
        }

        private string ParseHtml(string html)
        {
            Regex htmlRegex = new Regex("获取到授权码：[0-9]{6}");
            Match m = htmlRegex.Match(html);
            Regex pinRegex = new Regex("[0-9]{6}");
            Match m1 = pinRegex.Match(m.Value);
            return m1.Value;
        }
    }
}
